﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace CoTuong
{
    public class PacketData
    {
        public int preCot, preDong, cot, dong, luotdi;
        public bool isUndo;
        public PacketData(int preCot, int preDong, int cot, int dong, int luotdi, bool undo)
        {
            this.preCot = preCot;
            this.preDong = preDong;
            this.cot = cot;
            this.dong = dong;
            this.luotdi = luotdi;
            this.isUndo = undo;
        }
    }

    public class NetworkGame : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Game m_game; 
        VanCo VanCoNetWork;
        SpriteBatch spriteBatch;
        SpriteFont myFont;

        public static NetworkSession networkSession;
        public static PacketWriter packetWriter = new PacketWriter();
        public static PacketReader packetReader = new PacketReader();
        public static List<String> listGamerTag = new List<String>();

        public enum ColorChess { Red, Green };

        private bool isJoiningSession;
        private bool isHost;
        private bool delayToDrawMessage;
        private bool InitMatch = false;
        private bool startGame;

        public static bool RemoveMenuGUI;

        public int colorChess;

        public NetworkGame(Game game)
            : base(game)
        {
            m_game = game;
            delayToDrawMessage = true;
            networkSession = null;
        }

        public override void Initialize()
        {
            if (Menu.CreateHost)
            {
                isHost = true;
                colorChess = (int)ColorChess.Red;
            }
            else
            {
                isHost = false;
                colorChess = (int)ColorChess.Green;
            }
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            myFont = Game.Content.Load<SpriteFont>(@"Font\myFont");
            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            try
            {
                if (networkSession == null)
                    UpdatingNetwork(gameTime);
                else
                    UpdateNetworkSession(gameTime);
            }
            catch (Exception e)
            {
                Game1.errorMessage = e.Message;
            }
            base.Update(gameTime);
        }

        
        
        private void UpdatingNetwork(GameTime gameTime)
        {
            if (Game.IsActive)
            {
                if (Gamer.SignedInGamers.Count == 0)
                {
                    // If there are no profiles signed in, we cannot proceed.
                    // Show the Guide so the user can sign in.
                    Guide.ShowSignIn(1, false);
                }

                //--------------Host Side-----------
                //Tạo Host
                else if (isHost)
                {
                    networkSession = NetworkSession.Create(NetworkSessionType.SystemLink,
                                                           2, 2);

                    //Đã tạo host, chờ cho người chơi khác kết nối vào.
                    Menu.isWaitingForPlayer = true;
                    HookSessionEvents();
                }
                //----------------------------------



                //-------------Client Side----------
                //Tham gia 1 host
                else if (!isHost)
                {
                    JoinSession();
                }
                //----------------------------------
            }
        }

        

        private void JoinSession()
        {
            isJoiningSession = true;
            
            if (!delayToDrawMessage)
            {
                //Tìm host
                using (AvailableNetworkSessionCollection availableSessions =
                            NetworkSession.Find(NetworkSessionType.SystemLink, 2, null))
                {
                    delayToDrawMessage = true;
                    if (availableSessions.Count == 0)
                    {
                        isJoiningSession = false;
                        Menu.isHostNotFound = true;
                        Menu.CancelNetworkGame = true;
                        return;
                    }

                    //join host
                    networkSession = NetworkSession.Join(availableSessions[0]);

                    HookSessionEvents();
                    isJoiningSession = false;
                }
            }

        }

        private void HookSessionEvents()
        {
            networkSession.GamerJoined += GamerJoinedEventHandler;
            networkSession.SessionEnded += SessionEndedEventHandler;
            
        }

        private void GamerJoinedEventHandler(object sender, GamerJoinedEventArgs e)
        {
            int gamerIndex = networkSession.AllGamers.IndexOf(e.Gamer);

            e.Gamer.Tag = new PacketData(-1, -1, -1, -1, 0, false);
        }

        private void SessionEndedEventHandler(object sender, NetworkSessionEndedEventArgs e)
        {
            networkSession.Dispose();
            networkSession = null;
        }

        private void EndGetProfile(IAsyncResult result)
        {
            int currentGamer = (int)result.AsyncState;
            int nextGamer = currentGamer + 1;
            listGamerTag.Add(networkSession.AllGamers[currentGamer].Gamertag.ToString());
            if (nextGamer < networkSession.AllGamers.Count)
                networkSession.AllGamers[nextGamer].BeginGetProfile(EndGetProfile, nextGamer);
        }

        private void UpdateNetworkSession(GameTime gameTime)
        {
            if (networkSession == null)
            {
                Game1.showMainMenu = true;
                return;
            }
            networkSession.Update();

            if (!InitMatch && !startGame)
            {
                //Người chơi vừa tham gia gửi tín hiệu cho máy chủ và bắt đầu
                //khởi tạo ván đấu
                if (!isHost)
                {
                    foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
                    {
                        InitMatch = true;
                        packetWriter.Write(InitMatch);
                        gamer.SendData(packetWriter, SendDataOptions.InOrder);
                    }           
                }
                else
                {
                    foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
                    {
                        while (gamer.IsDataAvailable)
                        {
                            NetworkGamer sender;

                            //Nhận dữ liệu
                            gamer.ReceiveData(packetReader, out sender);

                            if (sender.IsLocal)
                                continue;

                            InitMatch = packetReader.ReadBoolean();
                        }
                    }
                }
            }

            //Khởi tạo ván đấu cho 2 người chơi
            else if(InitMatch)
            {
                VanCoNetWork = new VanCo(m_game, this);
                Menu.isWaitingForPlayer = false;
                InitMatch = false;
                RemoveMenuGUI = true;
                startGame = true;

                //Lấy thông tin của 2 đối thủ
                networkSession.AllGamers[0].BeginGetProfile(EndGetProfile, 0);
            }

            if(startGame)
            {
                VanCoNetWork.UpdateNetwork(gameTime);
            }
        }


        public override void Draw(GameTime gameTime)
        {
            delayToDrawMessage = false;
            if (!InitMatch)
            {
                if (isJoiningSession)
                    DrawMessage("Joining a Host....");
            }

            if (startGame)
            {
                VanCoNetWork.DrawNetwork(gameTime);
            }

            base.Draw(gameTime);
        }

        private void DrawMessage(string message)
        {
            spriteBatch.Begin();
            spriteBatch.DrawString(myFont, message, new Vector2(161, 161), Color.Black);
            spriteBatch.DrawString(myFont, message, new Vector2(160, 160), Color.White);
            spriteBatch.End();
        }

    }
}
